#include "stdafx.h"
#include "../NetworkIOModelLib/NetworkIOModelLib.h"


#ifdef _DEBUG
#pragma comment(lib, "../Debug/NetworkIOModelLib.lib")
#else
#pragma comment(lib, "../Release/NetworkIOModelLib.lib")
#endif


const TCHAR* ServerIP = _T("10.10.10.1");
const WORD ServerPort = 10002;
const DWORD TryToConnectCount = 10000;
DWORD AcceptedCount = 0;
const DWORD TryToSendCount = 100;
DWORD TotalRecvedBytes = 0;

void DoNetworkTest(INetworkLib* pNetworkLib)
{
	pNetworkLib->Initialize(
		[](SOCKET socket, DWORD error){
			printf("OnConnect(%d) error(%d)\n", socket, error);
	}	
	,	[&](SOCKET socket){ 
		InterlockedIncrement(&AcceptedCount);
		printf("[%d] OnAccept(%d)\n", AcceptedCount, socket);
		
		for(DWORD i = 0; i < TryToSendCount; ++i)
		{
			IStreamBuffer* pStreamBuffer = StreamBuffer::CreateComponent();
			pStreamBuffer->Write("helloworld", 10);
			pNetworkLib->Send(socket, *pStreamBuffer);
		}			
	}
	,	[](SOCKET socket){ 
		printf("OnDisconnect(%d)\n", socket);	
	}
	,	[&](SOCKET socket, IStreamBuffer* pStreamBuffer){ 
		InterlockedExchangeAdd(&TotalRecvedBytes, pStreamBuffer->GetLength());
		printf("OnRecv(%d) bytes(%d) totalBytes(%d)\n", socket, pStreamBuffer->GetLength(), TotalRecvedBytes); 
		pStreamBuffer->Release();
	}
	);
	pNetworkLib->Listen(ServerIP, ServerPort, 100);
	while(1)
	{
		SleepEx(INFINITE, true);
	}
	pNetworkLib->Release();
}

TEST(NetworkLib, BlockingModel)
{	
	DoNetworkTest(BlockingModelLib::CreateComponent());
}

TEST(NetworkLib, SelectModel)
{	
	DoNetworkTest(SelectModelLib::CreateComponent());
}

TEST(NetworkLib, WSAAsyncSelectModel)
{	
	DoNetworkTest(WSAAsyncSelectModelLib::CreateComponent());
}

TEST(NetworkLib, WSAEventSelectModel)
{	
	DoNetworkTest(WSAEventSelectModelLib::CreateComponent());
}

TEST(NetworkLib, OverlappedCompletionRoutineModel)
{	
	DoNetworkTest(OverlappedCompletionRoutineModelLib::CreateComponent());
}

TEST(NetworkLib, OverlappedIOCPModel)
{	
	DoNetworkTest(OverlappedIOCPModelLib::CreateComponent());
}